#include "MenuComponent.h"

namespace ds {

MenuComponent::MenuComponent(const std::string& name,const std::string& materialName,const std::string& layerName) : GroupNode(name,materialName,true) 
	, m_Name(name)
	, m_Material(materialName) 
	, m_TextCounter(0) 
	, m_LayerName(layerName)
	, m_NextStateName("") 
	, m_SelectedID(-1)
	, m_Offset(Vec2(0,0)) {
		m_LinkColor = ds::Color(1.0f,0.5f,0.0f,1.0f);
		m_HoverColor = ds::Color(0.0f,0.5f,1.0f,1.0f);
		gEngine->addMouseController(this);
		m_Sprites = new SpriteNode(name+"Sprites",m_Material);
		addNode(m_Sprites);
		//WorldLayer wl = gEngine->getWorld().getLayerByName(m_LayerName.c_str());
		//gEngine->getWorld().attachNode(m_Sprites,wl);	
}

void MenuComponent::addLink(int id,const std::string& textNodeName,int x,int y,int width,int height,const std::string& txt,const Color& color) {
	ds::PlainTextNode* tn = m_TextNodeMap[textNodeName];
	if ( tn != 0 ) {
		tn->setText("Text"+string::to_string(id),ds::Vec2(x,y),color,"%s",txt.c_str());
		MenuLink ml;
		ml.id = id;
		ml.pos = Vec2(x,y);
		ml.extent = Vec2(width,height);
		ml.text = txt;
		ml.active = true;
		m_Links.push_back(ml);
	}
}

void MenuComponent::setLinkState(int id,const std::string& textNodeName,bool state) {
	ds::PlainTextNode* tn = m_TextNodeMap[textNodeName];
	if ( tn != 0 ) {
		ds::TextLine* tl = tn->getText("Text"+string::to_string(id));
		for ( size_t i = 0; i < m_Links.size(); ++i ) {
			MenuLink* ml = &m_Links[i];
			if ( ml->id == id ) {
				ml->active = state;
			}
		}
		tl->active = state;
	}
}

void MenuComponent::setLinkColor(int id,const std::string& textNodeName,const Color& color) {
	ds::PlainTextNode* tn = m_TextNodeMap[textNodeName];
	if ( tn != 0 ) {
		ds::TextLine* tl = tn->getText("Text"+string::to_string(id));
		tl->color = color;
	}
}

void MenuComponent::setLinkColor(int id,const Color& color) {
	if ( id != -1 ) {
		TextNodeMap::iterator it = m_TextNodeMap.begin();
		while ( it != m_TextNodeMap.end() ) {
			ds::PlainTextNode* tn = it->second;
			ds::TextLine* tl = tn->getText("Text"+string::to_string(id));
			if ( tl != 0 ) {
				tl->color = color;
			}
			++it;
		}
	}
}

void MenuComponent::update(float elapsedTime) {
	if ( isActive() ) {
		int id = -1;
		Vec2 mp = gEngine->getMousePosition();
		mp += m_Offset;
		for ( size_t i = 0; i < m_Links.size(); ++i ) {
			MenuLink* ml = &m_Links[i];
			if ( ml->active && isInside(mp,ml) ) {
				id = ml->id;
			}
		}
		if ( m_SelectedID == -1 && id != -1 ) {
			m_SelectedID = id;
			setLinkColor(id,m_HoverColor);
		}
		else if ( m_SelectedID != -1 && id == -1 ) {
			setLinkColor(m_SelectedID,m_LinkColor);
			m_SelectedID = id;		
		}
		else if ( m_SelectedID != -1 && id != -1 && m_SelectedID != id ) {
			setLinkColor(m_SelectedID,m_LinkColor);
			m_SelectedID = id;		
			setLinkColor(id,m_HoverColor);
		}
	}
}

void MenuComponent::OnButtonUp( int button ) {
	if ( isActive() && m_Pressed ) {	
		m_Pressed = false;
		bool clicked = false;
		Vec2 mp = gEngine->getMousePosition();
		mp += m_Offset;
		for ( size_t i = 0; i < m_Links.size(); ++i ) {
			MenuLink* ml = &m_Links[i];
			if ( ml->active && isInside(mp,ml) ) {
				clicked = true;
				MenuEvent me;
				me.id = ml->id;
				me.type = 2;
				FIRE_EVENT(100,&me,sizeof(MenuEvent));
			}
		}
		if ( !clicked ) {
			MenuEvent me;
			me.id = -1;
			me.type = 1;
			FIRE_EVENT(100,&me,sizeof(MenuEvent));
		}
	}
}

bool MenuComponent::isInside(const Vec2& mousePos,MenuLink* menuLink) const {
	float xw = menuLink->pos.x + menuLink->extent.x;
	float yh = menuLink->pos.y + menuLink->extent.y;
	if ( mousePos.x < menuLink->pos.x ) {
		return false;
	}
	else if ( mousePos.x > xw ) {
		return false;
	}
	else if ( mousePos.y < menuLink->pos.y ) {
		return false;
	}
	else if ( mousePos.y > yh ) {
		return false;
	}
	return true;
}


}
